/*
 * Copyright 2019 F1ReKing.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.serialport.utils;

/**
 * @author F1ReKing
 * @date 2019/11/1 14:08
 * @Description
 */
public class ByteUtils {

    public static int isOdd(int num) {
        return num & 0x1;
    }

    public static int HexToInt(String inHex) {
        return Integer.parseInt(inHex, 16);
    }

    public static byte HexToByte(String inHex) {
        return (byte) Integer.parseInt(inHex, 16);
    }

    public static byte[] hexToByteArr(String hex) {
        int hexLen = hex.length();
        byte[] result;
        if (isOdd(hexLen) == 1) {
            hexLen++;
            result = new byte[hexLen / 2];
            hex = "0" + hex;
        } else {
            result = new byte[hexLen / 2];
        }
        int j = 0;
        for (int i = 0; i < hexLen; i += 2) {
            result[j] = HexToByte(hex.substring(i, i + 2));
            j++;
        }
        return result;
    }

    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }
    public static String CRC16(String str) {
        int[] DATA = hexStringToInts(str);
        int CRC_POLYNOM = 0xA001; // 多项式：X16 + X12 + X5 + 1 -> CRC_POLYNOM = 0x8408;
        int CRC_PRESET = 0xFFFF; // 初始值：0xFFFF -> CRC_PRESET = 0xFFFF;
        int crc = CRC_PRESET;
        int cnt = DATA.length;
        for (int i = 0; i < cnt; i++) // cnt – 协议数据长度（不包含CRC和开始位）
        {
            crc ^= DATA[i];
            for (int j = 0; j < 8; j++) {
                if ((crc & 0x0001) != 0)
                    crc = ((crc >> 1) ^ CRC_POLYNOM);
                else
                    crc = (crc >> 1);
            }
        }
        String crcHex = Integer.toHexString(crc).toUpperCase();
        crcHex = "0000".substring(0, 4 - crcHex.length()) + crcHex;
        //Toast.makeText(this, crcHex, Toast.LENGTH_SHORT).show();
        return crcHex.substring(2) + crcHex.substring(0, 2);
    }
    public static int[] hexStringToInts(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        int[] d = new int[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (int) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }

    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }
}
